小编典典

为什么我必须“git push --set-upstream origin“?

all

我创建了一个本地分支来测试 Solaris 和 Sun Studio。然后我将分支推向上游。提交更改并尝试推送更改后:

$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
 1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin solaris

为什么我必须为此做一些特别的事情?

是否有任何合理的用例有人会创建<branch>,将其推<branch>送到远程,然后声称<branch>不应该提交提交<branch>



这是另一台机器上的视图。分支显然存在,所以它被创建并推送:

$ git branch -a
  alignas
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris

阅读 256

收藏
2022-05-06

共1个答案

小编典典

TL;博士:git branch --set-upstream-to origin/solaris


您提出的问题的答案——我将重新表述为“我必须设置上游”吗?”:不,您根本不必 设置 上游。

但是,如果您没有当前分支的上游,Git 会在git push和其他命令上更改其行为。

这里完整的推送故事又长又无聊,可以追溯到 Git 1.5 版之前的历史。为了缩短它很多,git push实施得很差。1 从 Git 2.0
版开始,Git 现在有一个拼写为的配置旋钮push.default,现在默认为simple. 对于 2.0 之前和之后的几个版本的
Git,每次运行时git push,Git 都会发出很多噪音,试图说服你设置push.default只是为了让你git push闭嘴。

您没有提及您正在运行哪个版本的 Git,也没有提及您是否已配置push.default,所以我们必须猜测。我的猜测是您使用的是 Git 版本
2-point-something,并且您已设置push.defaultsimple使其关闭。由于那漫长而无聊的历史,确切地说你拥有哪个版本的
Git,以及如果你push.default设置了什么, 确实 很重要,但最后,你从 Git 收到另一个投诉的事实表明你的 Git
配置为避免过去的错误之一。

什么是上游?

上游 只是另一个分支名称,通常是远程跟踪分支,与(常规,本地)分支相关联。

每个分支都可以选择拥有一 (1) 个上游集。也就是说,每个分支要么有上游,要么没有上游。任何分支都不能有多个上游。

上游 应该 但不一定是一个有效的分支(无论是远程跟踪还是本地跟踪)。也就是说,如果当前分支 B 有上游 U应该可以
工作。如果它不起作用——如果它抱怨 U 不存在——那么大多数 Git
的行为就像根本没有设置上游一样。一些命令,如,将显示上游设置,但将其标记为“已消失”。origin/ _B_``master git rev-parse _U_ ____git branch -vv

上游有什么好处?

如果你push.default的设置为simpleor upstream,上游设置将 make git push,不带额外参数使用,正常工作。

就是这样——这就是它所做的一切git push。但这相当重要,因为这git push是一个简单的错字会引起严重头痛的地方之一。

如果您push.default的设置为nothingmatchingcurrent,则设置上游对git push.

(所有这些都假设您的 Git 版本至少为 2.0。)

上游影响git fetch

如果您在git fetch没有附加参数的情况下运行,Git会通过咨询当前分支的上游来确定要从 哪个 远程获取。如果上游是远程跟踪分支,Git
从该远程获取。(如果上游没有设置或者是本地分支,Git 会尝试 fetching origin。)

上游git mergegit rebase有影响

如果您运行git mergegit rebase没有其他参数,Git 将使用当前分支的上游。所以它缩短了这两个命令的使用。

上游影响git pull

无论如何你都不应该使用2git pull,但如果你这样做git pull了,使用上游设置来确定从哪个远程获取,然后与哪个分支合并或变基。也就是说,git pull做与git fetch“因为它实际 运行
”相同的事情,然后做与or相同的事情,因为它实际 运行 or 。git fetch``git merge``git rebase __git merge``git rebase

(你通常应该只手动完成这两个步骤,至少直到你对 Git 足够了解,以至于当任何一个步骤失败时,他们最终会认识到哪里出了问题并知道如何处理它。)

上游影响git status

这实际上可能是最重要的。一旦你有一个上游集,git status就可以报告你当前分支与其上游之间的差异,就提交而言。

如果像正常情况一样,您在 B 其上游设置为的分支上,并且您运行,您将立即看到您是否有可以推送的提交,和/或可以合并或变基的提交。origin/ _B_``git status

这是因为git status运行:

  • git rev-list --count @{u}..HEAD: 你有多少 B 未提交的提交?origin/ _B_
  • git rev-list --count HEAD..@{u}: 你有多少未提交的提交?origin/ _B_ B

设置上游可以为您提供所有这些东西。

怎么master已经有上游集了?

当您第一次从某个远程克隆时,使用:

$ git clone git://some.host/path/to/repo.git

或类似的,Git 所做的最后一步本质上是git checkout master. 这将检查您的本地分支机构——
只有master您没有本地分支机构。 __master

另一方面,您 确实 有一个名为 的远程跟踪分支origin/master,因为您刚刚克隆了它。

Git 猜测你的意思一定是:“让我成为一个新的本地人master,它指向与 remote-tracking
相同的提交origin/master,并且,当你在它的时候,将上游设置为masterto origin/master。”

这发生在您尚未拥有的 每个 分支上。git checkoutGit 创建分支 使其“跟踪”(作为上游)相应的远程跟踪分支。

但这不适用于 分支,即还没有远程跟踪分支的 分支

如果您创建一个 分支:

$ git checkout -b solaris

目前还没有origin/solaris。您的本地solaris 无法 跟踪远程跟踪分支origin/solaris,因为它不存在。

首次推送新分支时:

$ git push origin solaris

在 上创建 因此也在您自己的 Git 存储库中创建。但为时已晚:您已经有一个没有 upstream
的本地。3solaris``origin``origin/solaris``solaris __

Git不应该现在自动将其设置为上游吗?

大概。 请参阅“实施不佳”和脚注 1。现在 很难改变:有数百万个脚本使用 Git,其中一些很可能取决于其当前行为。改变行为需要一个新的主要版本,nag-
ware 强制你设置一些配置字段,等等。简而言之,Git
是其自身成功的牺牲品:无论它在今天出现的任何错误,只有在更改大多不可见、明显更好或随着时间的推移缓慢完成的情况下才能修复。

事实是,今天不会, 除非 您在. 这就是信息告诉你的。--set-upstream``-u``git push

你不必那样做。好吧,正如我们上面提到的,您根本不必这样做,但是假设您 想要 一个上游。您已经通过较早的推送solaris
上创建了分支,并且正如您的输出所示,您已经 本地存储库中拥有。origin``git branch __origin/solaris

您只是没有将其设置为solaris.

要现在设置它,而不是在第一次推送期间,请使用git branch --set-upstream-to. 子命令采用任何现有分支的--set- upstream-to名称,例如origin/solaris,并将当前分支的上游设置为另一个分支。

就是这样——这就是它所做的一切——但它具有上述所有含义。这意味着您可以只运行git fetch,然后环顾四周,然后运行git mergegit rebase酌情运行,然后进行新的提交并运行git push,而无需进行一堆额外的大惊小怪。


1公平地说,当时并不清楚最初的实施是否容易出错。只有当每个新用户每次都犯同样的错误时,这一点才变得清晰起来。现在是“不那么穷”,并不是说“好”。

2 “从不”有点强,但我发现当我将步骤分开时,Git 新手会更好地理解事物,特别是当我可以向他们展示git fetch实际做了什么,然后他们可以看到接下来会做什么git mergegit rebase将要做什么。

3如果你运行你的 第一个 git push作为——即git push -u origin solaris,如果你添加-u标志——如果(且仅当)推送成功,它将设置origin/solaris为当前分支的上游。所以你应该-u在第
一次 推送时提供。事实上,您可以在以后的任何推送中提供它,它会在那时设置 或更改 上游。但我认为git branch --set- upstream-to更容易,如果你忘记了。

4无论如何,通过简单地说“一个 MILL-YUN”的 Austin Powers / Dr Evil 方法来衡量。

2022-05-06